package com.union.official.common.constant;

import cn.hutool.core.collection.CollectionUtil;
import org.apache.commons.lang3.StringUtils;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 数字常量类
 *
 * @author 杨 强
 * @package com.union.official.common.constant
 * @createTime 2023-09-06 17:57
 */
public class NumConstant {

    public static final int ZERO = 0;
    public static final int ONE = 1;
    public static final int TWO = 2;
    public static final int THREE = 3;
    public static final int FOUR = 4;
    public static final int FIVE = 5;
    public static final int SIX = 6;
    public static final int SEVEN = 7;
    public static final int EIGHT = 8;
    public static final int NINE = 9;
    public static final int TEN = 10;
    public static final int ELEVEN = 11;
    public static final int TWELVE = 12;
    public static final int THIRTEEN = 13;
    public static final int FOURTEEN = 14;
    public static final int FIFTEEN = 15;
    public static final int TWENTY = 20;
    public static final int TWENTY_FIVE = 25;
    public static final int THIRTY = 30;
    public static final int SIXTY = 60;
    public static final int HUNDRED = 100;
    public static final int THOUSAND = 1000;
    public static final int IT_NUMBER = 1024;
    public static final long ZERO_LONG = 0L;
    public static final long ONE_LONG = 1L;
    public static final int TWO_HUNDRED = 200;
    public static final String ZERO_STRING = "0";
    public static final BigDecimal HUNDRED_DECIMAL = new BigDecimal("100");
    public static final BigDecimal THOUSAND_DECIMAL = new BigDecimal("1000");

    /**
     * 将分转为元
     * 若为整数，则只显示整数位
     * 若为小数，则保留两位小数
     * @param cent 分
     * @return Yuan 9 or 9.99
     */
    public static String transCentToYuan(int cent) {
        // 没有余数直接相除(相除后没有小数)
        if (cent % HUNDRED == ZERO) {
            return Integer.toString(cent / HUNDRED);
        }

        // 保留2为小数
        return new BigDecimal(String.valueOf(cent)).divide(HUNDRED_DECIMAL, 2, BigDecimal.ROUND_HALF_UP).toString();
    }

    /**
     * 金额乘以千分比
     * @param bg 金额
     * @param percentage 千分比
     * @return 四舍五入取整 70.333 = 70.33
     */
    public static BigDecimal percentage(BigDecimal bg, BigDecimal percentage){
        if (percentage == null || BigDecimal.ZERO.compareTo(percentage) == 0 ||
                bg == null || BigDecimal.ZERO.compareTo(bg) == 0){
            return BigDecimal.ZERO;
        }

        // 千分分比转为小数, 50‰ ->  乘以 0.005
        BigDecimal result = percentage.divide(THOUSAND_DECIMAL,4, RoundingMode.HALF_UP);

        // 保留2为小数, 舍入模式为:四舍五入
        return bg.multiply(result).setScale(2, RoundingMode.HALF_UP);
    }

    /**
     * 金额乘以千分比
     * 直接得到扣除手续费后的金额一般是向下取整
     * @param bg 金额
     * @param percentage 千分比
     * @return 向下取整 70.333 = 70.34
     */
    public static BigDecimal percentageByDown(BigDecimal bg, BigDecimal percentage){
        if (percentage == null || BigDecimal.ZERO.compareTo(percentage) == 0 ||
                bg == null || BigDecimal.ZERO.compareTo(bg) == 0){
            return BigDecimal.ZERO;
        }

        // 千分分比转为小数, 50‰ ->  乘以 0.005
        BigDecimal result = percentage.divide(THOUSAND_DECIMAL,4, RoundingMode.HALF_UP);

        // 保留2为小数, 舍入模式为:向下取整
        return bg.multiply(result).setScale(2, RoundingMode.DOWN);
    }

    /**
     * 金额乘以千分比
     * 计算手续费一般都是向上取整
     * @param bg 金额
     * @param percentage 千分比
     * @return 向上舍入   70.333 = 70.34
     */
    public static BigDecimal percentageByUp(BigDecimal bg, BigDecimal percentage){
        if (percentage == null || BigDecimal.ZERO.compareTo(percentage) == 0 ||
                bg == null || BigDecimal.ZERO.compareTo(bg) == 0){
            return BigDecimal.ZERO;
        }

        // 千分分比转为小数, 50‰ ->  乘以 0.005
        BigDecimal result = percentage.divide(THOUSAND_DECIMAL,4, RoundingMode.HALF_UP);

        // 保留2为小数, 舍入模式为:向上舍入
        return bg.multiply(result).setScale(2, RoundingMode.UP);
    }

    /**
     * 金额乘以百分比
     * @param bg 金额
     * @param percentage 百分比
     * @return 向上取整   70.333 = 70.34
     */
    public static BigDecimal percentageByHundred(BigDecimal bg, BigDecimal percentage){
        if (percentage == null || BigDecimal.ZERO.compareTo(percentage) == 0 ||
                bg == null || BigDecimal.ZERO.compareTo(bg) == 0){
            return BigDecimal.ZERO;
        }

        // 百分分比转为小数, 50‰ ->  乘以 0.05
        BigDecimal result = percentage.divide(HUNDRED_DECIMAL,4, RoundingMode.HALF_UP);

        // 保留2为小数, 舍入模式为:向上舍入
        return bg.multiply(result).setScale(2, RoundingMode.UP);
    }


    /**
     * 元转分
     * @param amount 元
     * @return 分
     */
    public static Integer yuanToFen(BigDecimal amount) {
        return amount.movePointRight(2).intValue();
    }

    /**
     * 分转元
     * @param amount 分
     * @return 元
     */
    public static BigDecimal fenToYuan(Integer amount) {
        if (amount == null || amount <= 0){
            return BigDecimal.ZERO;
        }
        BigDecimal fen = new BigDecimal(String.valueOf(amount));
        return fen.divide(HUNDRED_DECIMAL, 2, RoundingMode.HALF_UP);
    }

    /**
     * 格式化BigDecimal为字符串,保留2为小数
     * @param money BigDecimal
     * @return BigDecimal
     */
    public static String bgFormat(BigDecimal money) {
        if (money == null || money.compareTo(BigDecimal.ZERO) == 0) {
            return "0.00";
        }
       return new DecimalFormat("0.00").format(money);
    }

    /**
     * 多个BigDecimal求和
     * @param bdList
     * @return
     */
    public static BigDecimal dgAdd(List<BigDecimal> bdList) {
        if (CollectionUtil.isEmpty(bdList)){
            return BigDecimal.ZERO;
        }

        BigDecimal sum = new BigDecimal("0.00");

        for (BigDecimal bigDecimal : bdList) {
            if (bigDecimal == null || BigDecimal.ZERO.equals(bigDecimal)){
                continue;
            }
            sum = sum.add(bigDecimal);
            // 保留2位小数, 舍如模式选择四舍五入
            sum = sum.setScale(2, BigDecimal.ROUND_HALF_UP);
        }
        return sum;
    }

    /**
     * 数组转集合
     * @param split 数组
     * @param b 是否去重
     * @return
     */
    public static List<String> arrayToList(String[] split, boolean b) {
        List<String> list = new ArrayList<>();
        if (split == null || split.length <= 0){
            return list;
        }

        for (String s : split) {
            list.add(s);
        }

        if (b){
            return list.stream().distinct().collect(Collectors.toList());
        }

        return list;
    }

    public static BigDecimal formatBig(String str) {
        return new BigDecimal(StringUtils.isEmpty(str) ? "0.00" : str);
    }
}
